# print(markdown_content)
# #
# from docx import Document as DocxDocument
# from docx.oxml.ns import qn
# from docx.shared import Pt, RGBColor
# import re
# import os
#
#
# def docx_to_markdown(docx_path, image_dir="images"):
#     """
#     将 DOCX 文件转换为结构化的 Markdown 格式
#     保留标题层级、列表、表格、基本格式和图片
#     """
#     # 确保图片目录存在
#     os.makedirs(image_dir, exist_ok=True)
#
#     doc = DocxDocument(docx_path)
#     output = []
#
#     # 标题样式映射 (支持中文标题样式)
#     heading_map = {
#         '标题 1': '#',
#         '标题 2': '##',
#         '标题 3': '###',
#         '标题 4': '####',
#         '标题 5': '#####',
#         '标题 6': '######',
#         'Heading 1': '#',
#         'Heading 2': '##',
#         'Heading 3': '###',
#         'Heading 4': '####',
#         'Heading 5': '#####',
#         'Heading 6': '######'
#     }
#
#     # 遍历文档中的所有段落
#     for para in doc.paragraphs:
#         style_name = para.style.name
#
#         # 处理标题
#         if style_name in heading_map:
#             output.append(f"{heading_map[style_name]} {para.text}\n\n")
#             continue
#
#         # 处理列表
#         if is_list_item(para):
#             indent_level = get_list_indent_level(para)
#             list_char = get_list_char(para)
#             output.append(f"{'  ' * indent_level}{list_char} {para.text}\n")
#             continue
#
#         # 处理表格
#         if para.text == '' and para._element.tbl is not None:
#             tbl = para._element.tbl
#             md_table = convert_table_to_markdown(tbl)
#             output.append(md_table + "\n\n")
#             continue
#
#         # 处理普通段落
#         if para.text.strip():
#             text = apply_text_formatting(para)
#             output.append(text + "\n\n")
#
#     # 处理图片
#     for i, rel in enumerate(doc.part.rels.values()):
#         if "image" in rel.target_ref:
#             img_data = rel.target_part.blob
#             img_ext = get_image_extension(rel.target_ref)
#             img_filename = f"image_{i}{img_ext}"
#             img_path = os.path.join(image_dir, img_filename)
#
#             with open(img_path, "wb") as f:
#                 f.write(img_data)
#
#             # 获取图片标题 (如果存在)
#             caption = get_image_caption(doc, rel)
#             output.append(f"![{caption}]({img_path})\n\n")
#
#     # 后处理优化
#     markdown_content = ''.join(output)
#     markdown_content = post_process_markdown(markdown_content)
#
#     return markdown_content
#
#
# def is_list_item(para):
#     """检查段落是否为列表项"""
#     # 检查项目符号或编号
#     if para.text and para.text[0] in ['•', '▪', '-', '*', '·']:
#         return True
#
#     # 检查样式名称
#     if para.style.name.startswith('List') or para.style.name.startswith('列表'):
#         return True
#
#     # 检查段落属性中的列表标识
#     pPr = para._element.pPr
#     if pPr is not None:
#         if pPr.numPr is not None:
#             return True
#         if pPr.bullet is not None:
#             return True
#
#     return False
#
#
# def get_list_indent_level(para):
#     """获取列表缩进级别"""
#     indent_level = 0
#     pPr = para._element.pPr
#
#     if pPr is not None:
#         # 检查编号缩进
#         if pPr.numPr is not None:
#             for elem in pPr.numPr:
#                 if elem.tag.endswith('ilvl'):  # 缩进级别
#                     indent_level = int(elem.val) + 1
#
#         # 检查段落缩进
#         if pPr.ind is not None:
#             left_indent = pPr.ind.left
#             if left_indent is not None:
#                 # 每360缇(约0.25英寸)算一级缩进
#                 indent_level = max(indent_level, int(left_indent / 360))
#
#     return indent_level
#
#
# def get_list_char(para):
#     """获取列表符号"""
#     # 有序列表检测
#     pPr = para._element.pPr
#     if pPr is not None and pPr.numPr is not None:
#         for elem in pPr.numPr:
#             if elem.tag.endswith('numId'):
#                 # 有序列表使用数字
#                 return "1."
#
#     # 默认为无序列表
#     return "-"
#
#
# def convert_table_to_markdown(tbl):
#     """将Word表格转换为Markdown表格"""
#     rows = list(tbl.tr_like)
#     md_table = []
#
#     # 处理表头
#     header_cells = rows[0].tc_like
#     headers = [get_cell_text(cell) for cell in header_cells]
#     md_table.append('| ' + ' | '.join(headers) + ' |')
#     md_table.append('|' + '|'.join(['---'] * len(headers)) + '|')
#
#     # 处理数据行
#     for row in rows[1:]:
#         cells = row.tc_like
#         row_text = [get_cell_text(cell) for cell in cells]
#         md_table.append('| ' + ' | '.join(row_text) + ' |')
#
#     return '\n'.join(md_table)
#
#
# def get_cell_text(tc):
#     """从表格单元格中提取文本"""
#     text_parts = []
#     for child in tc.iterchildren():
#         if child.tag.endswith('p'):  # 段落
#             for run in child.iterchildren():
#                 if run.tag.endswith('r'):  # 文本运行
#                     for text_elem in run.iterchildren():
#                         if text_elem.tag.endswith('t'):  # 文本元素
#                             text_parts.append(text_elem.text or '')
#     return ''.join(text_parts).strip()
#
#
# def apply_text_formatting(para):
#     """应用基本文本格式"""
#     text = para.text
#
#     # 处理加粗、斜体、下划线
#     for run in para.runs:
#         run_text = run.text
#
#         if run.bold:
#             run_text = f"**{run_text}**"
#         if run.italic:
#             run_text = f"*{run_text}*"
#         if run.underline:
#             run_text = f"<u>{run_text}</u>"
#
#         # 替换原始文本
#         text = text.replace(run.text, run_text)
#
#     return text
#
#
# def get_image_extension(target_ref):
#     """获取图片扩展名"""
#     image_types = {
#         "png": ".png",
#         "jpeg": ".jpg",
#         "jpg": ".jpg",
#         "gif": ".gif",
#         "bmp": ".bmp",
#         "tiff": ".tiff"
#     }
#
#     for img_type, ext in image_types.items():
#         if img_type in target_ref.lower():
#             return ext
#
#     # 默认为.png
#     return ".png"
#
#
# def get_image_caption(doc, rel):
#     """尝试获取图片标题"""
#     # 检查图片下方的段落是否为标题
#     for paragraph in doc.paragraphs:
#         if paragraph.text.strip().lower().startswith(("figure", "图", "表")):
#             return paragraph.text.strip()
#
#     # 使用默认标题
#     return f"Image {rel.id}"
#
#
# def post_process_markdown(md_content):
#     """优化Markdown结构"""
#     # 1. 标准化标题
#     md_content = re.sub(r'(#{1,6}) ', r'\1 ', md_content)
#
#     # 2. 修复列表缩进
#     md_content = re.sub(r'(\n)([•▪·])', r'\1-', md_content)
#
#     # 3. 删除多余空行
#     md_content = re.sub(r'\n{3,}', '\n\n', md_content)
#
#     # 4. 添加表格分隔符
#     md_content = re.sub(r'(?<!\n)(\|.+\|\n)', r'\n\1', md_content)
#
#     # 5. 处理代码块
#     md_content = re.sub(r'```(.+?)```', r'\n```\1```\n', md_content, flags=re.DOTALL)
#
#     # 6. 移除文档末尾的多余空行
#     md_content = md_content.strip() + '\n'
#
#     return md_content
#
#
# # ==================== 使用示例 ====================
# if __name__ == "__main__":
#     # 转换单个文件
#     markdown_content = docx_to_markdown("D:\\hbyt\\AI智能投标\\2025_04_23_Word\\2025_04_23_Word\\Word\\1.0\\中文\\HR选育留用相关\\人员稳定性相关_v0.1_202304.docx")
#
#     # 保存结果
#     with open("output.md", "w", encoding="utf-8") as f:
#         f.write(markdown_content)
#
#     print("转换完成! 结果已保存到 output.md")
#
#
#     # 批量转换
#     def batch_convert_docx_to_markdown(input_dir, output_dir):
#         os.makedirs(output_dir, exist_ok=True)
#
#         for filename in os.listdir(input_dir):
#             if filename.endswith(".docx"):
#                 input_path = os.path.join(input_dir, filename)
#                 output_path = os.path.join(output_dir, f"{os.path.splitext(filename)[0]}.md")
#
#                 try:
#                     markdown_content = docx_to_markdown(input_path)
#                     with open(output_path, "w", encoding="utf-8") as f:
#                         f.write(markdown_content)
#                     print(f"已转换: {filename} -> {os.path.basename(output_path)}")
#                 except Exception as e:
#                     print(f"转换失败 {filename}: {str(e)}")
#
#
#     # 使用示例
#     batch_convert_docx_to_markdown("D:\\hbyt\\AI智能投标\\2025_04_23_Word\\2025_04_23_Word\\Word\\1.0\\中文\\HR选育留用相关\\", "markdown_output")


from docx import Document as DocxDocument
from docx.oxml.ns import qn
from docx.shared import Pt, RGBColor
import re
import os
from difflib import SequenceMatcher
from docx.oxml.table import CT_Tbl
from docx.table import Table
from docx.text.paragraph import Paragraph


def docx_to_markdown(docx_path, image_dir="images"):
    """
    将 DOCX 文件转换为结构化的 Markdown 格式
    修复了列表项检测问题
    """
    # 确保图片目录存在
    os.makedirs(image_dir, exist_ok=True)
    doc = DocxDocument(docx_path)
    output = []
    # 标题样式映射 (支持中文标题样式)
    heading_map = {
        '标题 1': '#',
        '标题 2': '##',
        '标题 3': '###',
        '标题 4': '####',
        '标题 5': '#####',
        '标题 6': '######',
        'Heading 1': '#',
        'Heading 2': '##',
        'Heading 3': '###',
        'Heading 4': '####',
        'Heading 5': '#####',
        'Heading 6': '######'
    }
    output_md_path="D:\\hbyt\\AI智能投标\\markdown_output\\markdown_output.md"
    if doc.paragraphs:
        for para in doc.paragraphs:
            style_name = para.style.name
            # 处理标题
            if style_name in heading_map:
                output.append(f"{heading_map[style_name]} {para.text}\n\n")
                continue
            # 处理列表 - 使用更可靠的方法
            list_type = detect_list_type(para)
            if list_type:
                indent_level = get_list_indent_level(para)
                list_char = "-" if list_type == "bullet" else "1."
                output.append(f"{'  ' * indent_level}{list_char} {para.text}\n")
                continue
            # 处理普通段落
            if para.text.strip():
                text = apply_text_formatting(para)
                output.append(text + "\n\n")
    if doc.tables:
        # with open(output_md_path, 'w', encoding='utf-8') as f:
        #     for table_index, table in enumerate(doc.tables):
        #         print("ok")
        #         for i, row in enumerate(table.rows):
        #             cells = [cell.text.replace('\n', ' ').replace('\r', ' ').strip() for cell in row.cells]
        #             output.append('| ' + ' | '.join(cells) + ' |')
        #             if i == 0:
        #                 output.append('| ' + ' | '.join(['---'] * len(cells)) + ' |')
        #         f.write(f'### 表格 {table_index + 1}\n\n')
        #         f.write('\n'.join(output))
        #         f.write('\n\n')
        body_elements = list(doc.element.body)  # 获取所有段落或表格的底层 XML 元素
        with open(output_md_path, encoding='utf-8') as f:
            lines = f.readlines()
            # print(lines)
            table_count = 0
            para_text_buffer = ""
            para_line_number = 0  # 记录最后一个非空段落的“行号”
            for idx, element in enumerate(body_elements):
                line_number = idx + 1  # 从1开始计行
                if element.tag.endswith('}tbl'):  # 表格
                    table = Table(element, doc)
                    table_count += 1
                    # print(f'> 第 {para_line_number} 行段落内容：{para_text_buffer.strip() or "（空段）"}\n\n')
                    # f.write(f'### 表格 {table_count}（出现在文档第 {line_number} 行，紧跟在下列段落之后）\n\n')
                    # f.write(f'> 第 {para_line_number} 行段落内容：{para_text_buffer.strip() or "（空段）"}\n\n')
                    for i, line in enumerate(lines):
                        similarity = SequenceMatcher(None, para_text_buffer.strip(), line.strip()).ratio()
                        if similarity > 0.8:
                            for r_idx, row in enumerate(table.rows):
                                cells = [cell.text.replace('\n', ' ').replace('\r', ' ').strip() for cell in row.cells]
                                for i in range(len(output)):
                                    similarity = SequenceMatcher(None, para_text_buffer.strip(), output[i]).ratio()
                                    if similarity > 0.8:
                                        # output.append('| ' + ' | '.join(cells) + ' |')
                                        output.insert(i+1,'| ' + ' | '.join(cells) + ' |')
                                if r_idx == 0:
                                    output.append('| ' + ' | '.join(['---'] * len(cells)) + ' |')
    # f.write('\n'.join(output))
    # f.write('\n\n')
                # elif element.tag.endswith('}p'):  # 段落
                #     para = Paragraph(element, doc)
                #     text = para.text.strip()
                #     if text:
                #         para_text_buffer = text
                #         para_line_number = line_number  # 记录该段落的“行号”
    # print(output)
    for i in range(len(output)):
        print(output[i])
    if doc.part:
        if hasattr(doc, 'part') and hasattr(doc.part, 'rels'):
            for i, rel in enumerate(doc.part.rels.values()):
                if "image" in rel.target_ref:
                    try:
                        img_data = rel.target_part.blob
                        img_ext = get_image_extension(rel.target_ref)
                        img_filename = f"image_{i}{img_ext}"
                        img_path = os.path.join(image_dir, img_filename)
                        with open(img_path, "wb") as f:
                            f.write(img_data)
                        # 获取图片标题 (如果存在)
                        caption = get_image_caption(doc, rel)
                        output.append(f"![{caption}]({img_path})\n\n")
                    except Exception as e:
                        output.append(f"<!-- 图片提取失败: {str(e)} -->\n\n")

    # 遍历文档中的所有段落
    # for para in doc.paragraphs:
    #     print(para.text)
    #     style_name = para.style.name
    #
    #     # 处理标题
    #     if style_name in heading_map:
    #         output.append(f"{heading_map[style_name]} {para.text}\n\n")
    #         continue
    #
    #     # 处理列表 - 使用更可靠的方法
    #     list_type = detect_list_type(para)
    #     if list_type:
    #         indent_level = get_list_indent_level(para)
    #         list_char = "-" if list_type == "bullet" else "1."
    #         output.append(f"{'  ' * indent_level}{list_char} {para.text}\n")
    #         continue
    #
    #     # 处理表格
    #     # if para.text == '' and para._element.tbl is not None:
    #     #     tbl = para._element.tbl
    #     #     try:
    #     #         md_table = convert_table_to_markdown(tbl)
    #     #         output.append(md_table + "\n\n")
    #     #     except Exception as e:
    #     #         # 表格转换失败时使用简单格式
    #     #         output.append(f"<!-- 表格转换失败: {str(e)} -->\n\n")
    #     #     continue
    #
    #     # 处理普通段落
    #     if para.text.strip():
    #         text = apply_text_formatting(para)
    #         output.append(text + "\n\n")
    #
    # # 处理图片
    # if hasattr(doc, 'part') and hasattr(doc.part, 'rels'):
    #     for i, rel in enumerate(doc.part.rels.values()):
    #         if "image" in rel.target_ref:
    #             try:
    #                 img_data = rel.target_part.blob
    #                 img_ext = get_image_extension(rel.target_ref)
    #                 img_filename = f"image_{i}{img_ext}"
    #                 img_path = os.path.join(image_dir, img_filename)
    #
    #                 with open(img_path, "wb") as f:
    #                     f.write(img_data)
    #
    #                 # 获取图片标题 (如果存在)
    #                 caption = get_image_caption(doc, rel)
    #                 output.append(f"![{caption}]({img_path})\n\n")
    #             except Exception as e:
    #                 output.append(f"<!-- 图片提取失败: {str(e)} -->\n\n")
    # 后处理优化
    markdown_content = ''.join(output)
    markdown_content = post_process_markdown(markdown_content)
    return markdown_content


def detect_list_type(para):
    """
    更可靠地检测列表类型
    修复了 AttributeError: 'CT_PPr' object has no attribute 'bullet'
    """
    # 1. 检查文本开头的项目符号
    if para.text and para.text[0] in ['•', '▪', '-', '*', '·']:
        return "bullet"

    # 2. 检查样式名称
    style_name = para.style.name.lower()
    if "list" in style_name or "列表" in style_name:
        return "bullet" if "bullet" in style_name else "number"

    # 3. 检查段落属性中的列表标识
    pPr = para._element.pPr
    if pPr is not None:
        # 检查编号属性
        if pPr.numPr is not None:
            return "number"
        # 检查项目符号属性 - 使用更可靠的方法
        if hasattr(pPr, 'buFont') or hasattr(pPr, 'buChar') or hasattr(pPr, 'buAutoNum'):
            return "bullet"
    return None


def get_list_indent_level(para):
    """获取列表缩进级别"""
    indent_level = 0
    pPr = para._element.pPr
    if pPr is not None:
        # 检查编号缩进
        if pPr.numPr is not None:
            for elem in pPr.numPr:
                if elem.tag.endswith('ilvl'):  # 缩进级别
                    try:
                        indent_level = int(elem.val) + 1
                    except (ValueError, TypeError):
                        indent_level = 0

        # 检查段落缩进
        if hasattr(pPr, 'ind') and pPr.ind is not None:
            if hasattr(pPr.ind, 'left') and pPr.ind.left is not None:
                try:
                    # 每360缇(约0.25英寸)算一级缩进
                    left_indent = pPr.ind.left
                    indent_level = max(indent_level, int(left_indent / 360))
                except (TypeError, ValueError):
                    pass

    return indent_level

def convert_table_to_markdown(tbl):
    """将Word表格转换为Markdown表格 - 更健壮的版本"""
    try:
        rows = list(tbl.tr_like)
        if not rows:
            return ""
        # 处理表头
        header_cells = rows[0].tc_like
        if not header_cells:
            return ""
        headers = [get_cell_text(cell) for cell in header_cells]
        md_table = ['| ' + ' | '.join(headers) + ' |']
        md_table.append('|' + '|'.join(['---'] * len(headers)) + '|')
        # 处理数据行
        for row in rows[1:]:
            cells = row.tc_like
            if not cells:
                continue
            row_text = [get_cell_text(cell) for cell in cells]
            md_table.append('| ' + ' | '.join(row_text) + ' |')

        return '\n'.join(md_table)
    except Exception as e:
        # 表格转换失败时返回简单文本
        return f"<!-- 表格内容开始 -->\n{get_table_text(tbl)}\n<!-- 表格内容结束 -->"


def get_table_text(tbl):
    """提取表格文本作为回退方案"""
    rows = []
    for row in tbl.tr_like:
        row_text = []
        for cell in row.tc_like:
            row_text.append(get_cell_text(cell))
        rows.append(" | ".join(row_text))
    return "\n".join(rows)


def get_cell_text(tc):
    """从表格单元格中提取文本 - 更健壮的版本"""
    try:
        text_parts = []
        for child in tc.iterchildren():
            if child.tag.endswith('p'):  # 段落
                for run in child.iterchildren():
                    if run.tag.endswith('r'):  # 文本运行
                        for text_elem in run.iterchildren():
                            if text_elem.tag.endswith('t'):  # 文本元素
                                text_parts.append(text_elem.text or '')
        return ''.join(text_parts).strip()
    except:
        return ""


def apply_text_formatting(para):
    """应用基本文本格式"""
    text = para.text
    # 处理加粗、斜体、下划线
    for run in para.runs:
        run_text = run.text
        if not run_text:
            continue
        # 应用格式
        if run.bold:
            run_text = f"**{run_text}**"
        if run.italic:
            run_text = f"*{run_text}*"
        if run.underline:
            run_text = f"<u>{run_text}</u>"
        # 替换原始文本
        text = text.replace(run.text, run_text)
    return text


def get_image_extension(target_ref):
    """获取图片扩展名"""
    if not isinstance(target_ref, str):
        return ".png"

    image_types = {
        "png": ".png",
        "jpeg": ".jpg",
        "jpg": ".jpg",
        "gif": ".gif",
        "bmp": ".bmp",
        "tiff": ".tiff"
    }

    for img_type, ext in image_types.items():
        if img_type in target_ref.lower():
            return ext

    # 默认为.png
    return ".png"


def get_image_caption(doc, rel):
    """尝试获取图片标题 - 更健壮的版本"""
    try:
        # 检查图片下方的段落是否为标题
        for paragraph in doc.paragraphs:
            if paragraph.text.strip().lower().startswith(("figure", "图", "表")):
                return paragraph.text.strip()
    except:
        pass
    # 使用默认标题
    return f"Image {rel.id if hasattr(rel, 'id') else 'unknown'}"


def post_process_markdown(md_content):
    """优化Markdown结构"""
    # 1. 标准化标题
    md_content = re.sub(r'(#{1,6}) ', r'\1 ', md_content)
    # 2. 修复列表缩进
    md_content = re.sub(r'(\n)([•▪·])', r'\1-', md_content)
    # 3. 删除多余空行
    md_content = re.sub(r'\n{3,}', '\n\n', md_content)
    # 4. 添加表格分隔符
    md_content = re.sub(r'(?<!\n)(\|.+\|\n)', r'\n\1', md_content)
    # 5. 处理代码块
    md_content = re.sub(r'```(.+?)```', r'\n```\1```\n', md_content, flags=re.DOTALL)
    # 6. 移除文档末尾的多余空行
    md_content = md_content.strip() + '\n'
    return md_content


# ==================== 使用示例 ====================
if __name__ == "__main__":
    # 使用绝对路径转换文件
    input_path = "D:\\hbyt\\AI智能投标\\激励及绩效管理_v1.0_2201.docx"
    output_path = "D:\\hbyt\\AI智能投标\\markdown_output\\markdown_output111.md"
    try:
        markdown_content = docx_to_markdown(input_path)
        print(markdown_content)
        # 保存结果
        with open(output_path, "w", encoding="utf-8") as f:
            f.write(markdown_content)
        print(f"转换完成! 结果已保存到 {output_path}")
    except Exception as e:
        print(f"转换失败: {str(e)}")
        # 添加详细的错误信息
        import traceback
        traceback.print_exc()